const express = require('express');
const router = express.Router();
const VideoController = require('../controllers/videoController');
const { verifyAdmin, hashFile, ensureDirExists } = require('../utils/helpers');
const { videoUpload, coverUpload } = require('../utils/uploadHelper');
const adminAuth = require('../middleware/adminAuth');
const path = require('path');
const fs = require('fs');
const { saveChunk, getUploadedChunks, mergeChunks } = require('../utils/chunkHelper');
const multer = require('multer');
const upload = multer({ 
  dest: 'uploads/temp/',
  limits: {
    fileSize: 100 * 1024 * 1024 // 100MB per chunk
  }
});

// 管理端路由（需要验证管理员权限）
// 创建/上传视频（文件可选，若无文件则需提供 video_url）
// 兼容字段名 'video' 或 'file'
router.post('/admin/upload/video', 
  adminAuth,
  videoUpload.fields([{ name: 'video', maxCount: 1 }, { name: 'file', maxCount: 1 }]),
  (req, res, next) => {
    // 规范化 req.file，优先使用 'video'，否则使用 'file'
    if (!req.file) {
      if (req.files && Array.isArray(req.files.video) && req.files.video.length > 0) {
        req.file = req.files.video[0];
      } else if (req.files && Array.isArray(req.files.file) && req.files.file.length > 0) {
        req.file = req.files.file[0];
      }
    }
    next();
  },
  // 去重：同内容视频仅保留一份（按MD5命名）
  async (req, res, next) => {
    try {
      if (!req.file) return next();
      const filePath = req.file.path;
      const md5 = await hashFile(filePath);
      const ext = path.extname(req.file.originalname || req.file.filename || '');
      const videosDir = path.join(__dirname, '../uploads/videos');
      ensureDirExists(videosDir);
      const finalName = `${md5}${ext}`;
      const finalPath = path.join(videosDir, finalName);
      const existed = fs.existsSync(finalPath);
      if (existed) {
        // 已存在，删除临时文件，指向已存在文件
        fs.unlinkSync(filePath);
      } else {
        fs.renameSync(filePath, finalPath);
      }
      // 统一 filename 为去重后的文件名
      req.file.filename = finalName;
      req.file.path = finalPath;
      req.fileExisted = existed;
      next();
    } catch (e) {
      next(e);
    }
  },
  VideoController.uploadVideo
);

// 分片上传相关接口
// 检查已上传的分片
router.get('/admin/upload/chunks',
  adminAuth,
  async (req, res) => {
    try {
      const { fileIdentifier } = req.query;
      if (!fileIdentifier) {
        return res.status(400).json({ code: 400, msg: '缺少文件标识' });
      }
      
      const chunks = await getUploadedChunks(fileIdentifier);
      res.json({
        code: 200,
        msg: '获取成功',
        data: chunks
      });
    } catch (e) {
      console.error('获取已上传分片失败:', e);
      res.status(500).json({ code: 500, msg: '获取失败' });
    }
  }
);

// 上传单个分片
router.post('/admin/upload/chunk',
  adminAuth,
  upload.single('chunk'),
  async (req, res) => {
    try {
      if (!req.file) {
        return res.status(400).json({ code: 400, msg: '请上传分片文件' });
      }
      
      const { chunkIndex, totalChunks, fileIdentifier } = req.body;
      
      if (chunkIndex === undefined || totalChunks === undefined || !fileIdentifier) {
        fs.unlinkSync(req.file.path); // 删除临时文件
        return res.status(400).json({ code: 400, msg: '缺少必要参数' });
      }
      
      // 将分片移动到指定目录
      await saveChunk(fileIdentifier, parseInt(chunkIndex), fs.readFileSync(req.file.path));
      fs.unlinkSync(req.file.path); // 删除临时文件
      
      res.json({
        code: 200,
        msg: '分片上传成功'
      });
    } catch (e) {
      console.error('分片上传失败:', e);
      if (req.file && fs.existsSync(req.file.path)) {
        fs.unlinkSync(req.file.path);
      }
      res.status(500).json({ code: 500, msg: '分片上传失败' });
    }
  }
);

// 合并分片
router.post('/admin/upload/merge',
  adminAuth,
  async (req, res) => {
    try {
      const { fileIdentifier, fileName, totalChunks } = req.body;
      
      if (!fileIdentifier || !fileName || totalChunks === undefined) {
        return res.status(400).json({ code: 400, msg: '缺少必要参数' });
      }
      
      // 生成最终文件名（使用MD5）
      const ext = path.extname(fileName);
      const videosDir = path.join(__dirname, '../uploads/videos');
      ensureDirExists(videosDir);
      
      // 临时文件名
      const tempFileName = `${fileIdentifier}${ext}`;
      const tempPath = path.join(videosDir, tempFileName);
      
      // 合并分片
      await mergeChunks(fileIdentifier, tempPath, parseInt(totalChunks));
      
      // 计算文件MD5并重命名
      const md5 = await hashFile(tempPath);
      const finalName = `${md5}${ext}`;
      const finalPath = path.join(videosDir, finalName);
      
      let existed = false;
      if (fs.existsSync(finalPath)) {
        // 文件已存在，删除临时文件
        fs.unlinkSync(tempPath);
        existed = true;
      } else {
        // 重命名临时文件
        fs.renameSync(tempPath, finalPath);
      }
      
      const base = process.env.PUBLIC_BASE_URL || `${req.protocol}://${req.get('host')}`;
      res.json({
        code: 200,
        msg: existed ? '视频已存在，复用' : '视频上传成功',
        data: {
          url: `${base}/uploads/videos/${encodeURIComponent(finalName)}`,
          existed
        }
      });
    } catch (e) {
      console.error('合并分片失败:', e);
      res.status(500).json({ code: 500, msg: '合并分片失败: ' + (e.message || '未知错误') });
    }
  }
);

// 封面上传接口
router.post('/admin/upload/cover',
  adminAuth,
  coverUpload.single('cover'),
  (req, res, next) => {
    if (!req.file) {
      return res.status(400).json({
        code: 400,
        msg: '请上传封面图片'
      });
    }
    next();
  },
  // 封面去重：按MD5命名
  async (req, res) => {
    try {
      const filePath = req.file.path;
      const md5 = await hashFile(filePath);
      const ext = path.extname(req.file.originalname || req.file.filename || '');
      const coversDir = path.join(__dirname, '../uploads/covers');
      ensureDirExists(coversDir);
      const finalName = `${md5}${ext}`;
      const finalPath = path.join(coversDir, finalName);
      const existed = fs.existsSync(finalPath);
      if (existed) {
        fs.unlinkSync(filePath);
      } else {
        fs.renameSync(filePath, finalPath);
      }
      const base = process.env.PUBLIC_BASE_URL || `${req.protocol}://${req.get('host')}`;
      res.json({
        code: 200,
        msg: existed ? '封面已存在，复用' : '封面上传成功',
        data: {
          url: `${base}/uploads/covers/${encodeURIComponent(finalName)}`,
          existed
        }
      });
    } catch (e) {
      console.error(e);
      res.status(500).json({ code: 500, msg: '封面处理失败' });
    }
  }
);

// 仅上传视频文件，返回可访问URL（不入库）
router.post('/admin/upload/video-file',
  adminAuth,
  videoUpload.single('file'),
  async (req, res) => {
    try {
      if (!req.file) {
        return res.status(400).json({ code: 400, msg: '请上传视频文件' });
      }
      const filePath = req.file.path;
      const md5 = await hashFile(filePath);
      const ext = path.extname(req.file.originalname || req.file.filename || '');
      const videosDir = path.join(__dirname, '../uploads/videos');
      ensureDirExists(videosDir);
      const finalName = `${md5}${ext}`;
      const finalPath = path.join(videosDir, finalName);
      const existed = fs.existsSync(finalPath);
      if (existed) {
        fs.unlinkSync(filePath);
      } else {
        fs.renameSync(filePath, finalPath);
      }
      const base = process.env.PUBLIC_BASE_URL || `${req.protocol}://${req.get('host')}`;
      res.json({
        code: 200,
        msg: existed ? '视频已存在，复用' : '视频上传成功',
        data: { url: `${base}/uploads/videos/${encodeURIComponent(finalName)}`, existed }
      });
    } catch (e) {
      console.error(e);
      res.status(500).json({ code: 500, msg: '视频处理失败' });
    }
  }
);

router.put('/admin/:id', adminAuth, VideoController.editVideo);

router.delete('/admin/:id', adminAuth, VideoController.deleteVideo);

router.get('/admin/list', adminAuth, VideoController.getVideoList);

// 视频转码管理接口（管理端）
router.post('/admin/:id/transcode', adminAuth, VideoController.transcodeVideo);
router.get('/admin/check-transcode', adminAuth, VideoController.checkVideosTranscode);

// 公开接口（注意：具体路径的路由必须在参数路由之前）
router.get('/recommended', VideoController.getRecommendedVideos);
router.get('/search', VideoController.searchVideos);
router.get('/area/:areaId', VideoController.getVideosByArea);
router.get('/genre/:genreId', VideoController.getVideosByGenre);
router.get('/:id', VideoController.getVideoDetail);
router.post('/:id/play', VideoController.increasePlayCount);

module.exports = router;